home *** CD-ROM | disk | FTP | other *** search
/ Aminet 13 / Aminet 13 - August 1996.iso / Aminet / comm / maxs / CMaxGu16.lha / CydalMaxGuide16 / main.c < prev    next >
C/C++ Source or Header  |  1996-03-13  |  11KB  |  322 lines

  1. /* Filelist generator for MAX's BBS version 1.54                    */
  2. /* For SAS/C 6.55 - the BEST compiler. Too bad it's discontinued    */
  3. /* Anyone may use this for anything they want if they want to       */
  4. /* This was written after looking at the binary file FILE.DATA,     */
  5. /* I haven't actually seen any documentation on MAX's BBS, so don't */
  6. /* blame me if anything goes wrong :-)                              */
  7. /* V1.0 .. oh. I just discovered that i DO have some docs for MAX!  */
  8. /* V1.1 Small improvements                                          */
  9. /* V1.2 ditto                                                       */
  10. /* V1.3 Oh my god, who put all those bugs in my program ?           */
  11. /* V1.4 Wrapping routine for desc. improved slightly                */
  12.  
  13. #include <proto/dos.h>          /* C= */
  14. #include <proto/exec.h>
  15. #include <utility/tagitem.h>
  16. #include <exec/memory.h>
  17. #include <stdio.h>              /* SAS printf */
  18. #include <stdlib.h>             /*     qsort + atoi herfra */
  19. #include <string.h>             /*     strengbehandling */
  20. #include <ctype.h>              /*     isdigit */
  21.  
  22. #define SEKTIONER 100           /* Maksimum sektioner */
  23.  
  24. struct maxfileentry {
  25.   ULONG dato;                   /* Dato for fil anskaffelse - dage siden 01/01/78 */
  26.   ULONG pad1;
  27.   ULONG siz;                    /* Filstørrelse */
  28.   ULONG dlcount;                /* Antal gange downloadet */
  29.   UBYTE flags;
  30.   UBYTE area;                   /* Area filen hører til i */
  31.   UBYTE name[41];               /* Filnavn */
  32.   UBYTE desc[60];               /* Fil desc. */
  33.   UBYTE uploader[41];           /* Navn på uploader */
  34.   UBYTE unknown[42];            /* ?? evt. en sysop-kommentar, jeg er ikke sikker */
  35. };
  36.  
  37. struct maxfilelist {
  38.   UBYTE max[62];                /* MAX's text */
  39.   ULONG filetotal;              /* Antal filer på BBS */
  40.   ULONG filesarea[SEKTIONER];   /* Antal filer for hver sektion */
  41.   UBYTE the_rest;               /* Faktisk: struct maxfileentry files[?????] */
  42. };
  43.  
  44. char * __asm formatfile(register __a0 struct maxfileentry *argument, register __a1 char *datestr, register __d0 BOOL new);
  45.  
  46. BOOL hentfil(char *filnavnet, APTR *ptrptr, ULONG *sizptr)
  47. {
  48. struct FileInfoBlock *fib;
  49. BPTR filhandle;
  50.  
  51.   if (filhandle=Open(filnavnet,MODE_OLDFILE))
  52.   {
  53.     if (fib=AllocDosObjectTags(DOS_FIB,TAG_END))
  54.     {
  55.       if (ExamineFH(filhandle,fib))
  56.       {
  57.         if (*ptrptr=AllocVec(fib->fib_Size,MEMF_ANY))
  58.         {
  59.           if (fib->fib_Size==Read(filhandle,*ptrptr,fib->fib_Size))
  60.           {
  61.             *sizptr=fib->fib_Size;
  62.             FreeDosObject(DOS_FIB,fib);
  63.             Close(filhandle);
  64.             return(TRUE);
  65.           } else printf("Coulden't read file %s\n",filnavnet);
  66.           FreeVec(*ptrptr);
  67.         } else printf("No memory\n");
  68.       FreeDosObject(DOS_FIB,fib);
  69.       } else printf("AmigaDos won't cooperate!\n");
  70.     } else printf("REALLY no memory\n");
  71.     Close(filhandle);
  72.   } else printf("Coulden't open file %s\n",filnavnet);
  73.   return(FALSE);
  74. }
  75.  
  76. int comp(struct maxfileentry **fila, struct maxfileentry **filb)
  77. {
  78.   return(stricmp((*fila)->name,(*filb)->name));
  79. }
  80.  
  81. const char KarlEinar[]="$VER: MakeMaxGuide version 1.6 by Claus Dyring Jensen\n\0";
  82.  
  83. int main(int argc, char *argv[])
  84. {
  85. UBYTE *conmem;
  86. struct maxfilelist *srcmem;
  87. APTR *infmem;
  88. ULONG srcsiz, consiz, infsiz;
  89. BPTR filhandle;
  90. struct maxfileentry **sekarray[100];
  91. struct maxfileentry **sekarray2[100];
  92. struct maxfileentry **sekarrayptr;
  93. struct maxfileentry *filptr;
  94. int i,j;
  95. char *s;
  96. int files[100];
  97. struct DateTime datotid;
  98. struct DateStamp dato;
  99. char tidstreng[LEN_DATSTRING];
  100. BOOL inkluder[100];
  101. char filnavn[100];
  102. BOOL optionused;
  103. ULONG maxage=0;
  104. char *bbsname="Filelist generated by MakeMaxGuide";
  105. BOOL info=FALSE;
  106. BOOL simplelist=FALSE;
  107. ULONG totalareabytes;
  108.  
  109.   /* INIT THE DATESTAMP */
  110.   DateStamp(&dato);
  111.   /* INIT EXCLUDE ARRAY */
  112.   for(i=0;i<100;i++)
  113.     inkluder[i]=FALSE;
  114.   /* CHECK FOR SENSIBLE NUMBER OF ARGS */
  115.   if (argc<4 || argc/2*2!=argc)
  116.   {
  117.     printf("Usage: %s outfilename file.data maxxbbs.config s sections [a AGELIMIT] [n NAME] [i INFOPAGE] [m MODE]\n\n",argv[0]);
  118.     printf("You must supply full paths for the files.\nProper postfix will be added to outfilename.\n");
  119.     printf("SECTIONS is a string of sections to be included. Fx 20212223\n");
  120.     printf("AGELIMIT excludes files older than AGELIMIT days.\n");
  121.     printf("NAME is a string containing the name of your bbs.\n");
  122.     printf("INFOPAGE is the filename of an ascii text that may be included.\n");
  123.     printf("MODE can be \"Amigaguide\" or \"Textfile\" and defaults to Amigaguide.\n");
  124.     return(10);
  125.   }
  126.   /* CHECK FOR OPTIONS */
  127.   for(j=4;j<argc;j+=2)
  128.   {
  129.     optionused=FALSE;
  130.     /* OPT: INCLUDE AREAS */
  131.     if (tolower(argv[j][0])=='s')
  132.       if ((strlen(argv[j+1])&1)==0)
  133.       {
  134.         for(i=0;i<strlen(argv[j+1])/2;i++)
  135.           if (isdigit(argv[j+1][i*2]) && isdigit(argv[j+1][i*2+1]))
  136.             inkluder[(argv[j+1][i*2]-'0')*10+argv[j+1][i*2+1]-'0']=TRUE;
  137.           else
  138.           {
  139.             printf("Inclusion string contains non-digits\n");
  140.             return(10);
  141.           }
  142.           optionused=TRUE;
  143.       }
  144.       else
  145.       {
  146.         printf("Inclusion string should be even length\n");
  147.         return(10);
  148.       }
  149.     /* OPT: HE WANTS AN INFOPAGE TOO */
  150.     if (tolower(argv[j][0])=='i')
  151.       if (hentfil(argv[j+1],(APTR)&infmem,&infsiz))
  152.       {
  153.         info=TRUE;
  154.         optionused=TRUE;
  155.       }
  156.       else
  157.       {
  158.         printf("Couldn't open your infopage %s\n",argv[j+1]);
  159.         return(10);
  160.       }
  161.     /* OPT: THERE IS A NAME FOR THE BBS */
  162.     if (tolower(argv[j][0])=='n')
  163.     {
  164.       bbsname=argv[j+1];
  165.       optionused=TRUE;
  166.     }
  167.     /* OPT: MODE CHANGE */
  168.     if (tolower(argv[j][0])=='m' && (tolower(argv[j+1][0])=='t' || tolower(argv[j+1][0])=='a'))
  169.     {
  170.       if(tolower(argv[j+1][0])=='t')
  171.         simplelist=TRUE;
  172.       optionused=TRUE;
  173.     }
  174.     /* OPT: EXCLUDE FILES MORE THAN X DAYS OLD */
  175.     if (tolower(argv[j][0])=='a')
  176.     {
  177.       maxage=atoi(argv[j+1]);
  178.       optionused=TRUE;
  179.     }
  180.     if (!optionused)
  181.     {
  182.       printf("Option not recognized:%s %s\n?REDO FROM START\nREADY.\n",argv[j],argv[j+1]);
  183.       return(10);
  184.     }
  185.   }
  186.   /* ADD POSTFIX TO FILENAME */
  187.   strcpy(filnavn,argv[1]);
  188.   if(simplelist)
  189.     strcat(filnavn,".txt");
  190.   else
  191.     strcat(filnavn,".guide");
  192.   /* GET FILES NEEDED AND OPEN GUIDE FILE FOR WRITING */
  193.   if (hentfil(argv[2],(APTR)&srcmem,&srcsiz))
  194.   {
  195.     if (hentfil(argv[3],(APTR)&conmem,&consiz))
  196.     {
  197.       if (filhandle=Open(filnavn,MODE_NEWFILE))
  198.       {
  199.         /* I THOUGHT THIS WAS A TOTAL OF ALL FILES, BUT IT SEEMS MAX CAN'T COUNT :) */
  200.         /* SO I'LL JUST HAVE TO FIX THE VALUE MYSELF.. DAMN */
  201.         srcmem->filetotal=(srcsiz-466)/202;
  202.         if (sekarrayptr=(struct maxfileentry **)AllocVec(srcmem->filetotal*sizeof(struct maxfileentry **),MEMF_ANY))
  203.         {
  204.           /* INITIALIZE DATESTAMP */
  205.           datotid.dat_Stamp.ds_Days=dato.ds_Days;
  206.           datotid.dat_Stamp.ds_Minute=0;
  207.           datotid.dat_Stamp.ds_Tick=0;
  208.           datotid.dat_Format=FORMAT_DOS;
  209.           datotid.dat_Flags=0;
  210.           datotid.dat_StrDay=NULL;
  211.           datotid.dat_StrDate=tidstreng;
  212.           datotid.dat_StrTime=NULL;
  213.           DateToStr(&datotid);
  214.           /* COUNT FILES IN ALL AREAS (0-99) */
  215.           for(i=0;i<100;i++)
  216.             files[i]=0;
  217.           filptr=(struct maxfileentry *)&srcmem->the_rest;
  218.           for(i=0;i<srcmem->filetotal;i++)
  219.           {
  220.             if (!filptr->flags&~4)
  221.               if (!maxage || dato.ds_Days-filptr->dato<maxage)
  222.                 files[filptr->area]++;
  223.             filptr++;
  224.           }
  225.           /* OUTPUT INITIAL JUNK */
  226.           if(!simplelist)
  227.           {
  228.             FPrintf(filhandle,"@DATABASE \"%s\"\n",bbsname);
  229.             FPrintf(filhandle,"@NODE MAIN \"%s\"\n"\
  230.             "                    Filelist generation date: %s\n"\
  231.             "                            Table of Contents\n",bbsname,tidstreng);
  232.           }
  233.           /* OUTPUT INFOPAGE REFERENCE IF ANY */
  234.           if(info && !simplelist)
  235.           {
  236.             FPrintf(filhandle,"                      @{\" BBS information page          \" LINK infosektion}\n\n");
  237.           }
  238.           /* OUTPUT TITLEPAGE SECTION REFRENCES */
  239.           if(!simplelist)
  240.           {
  241.             for(i=0;i<100;i++)
  242.               if(inkluder[i] && files[i])
  243.                 FPrintf(filhandle,"                      @{\" %-30.30s\" LINK section%ld}\n",conmem+2496+i*62,(LONG)i);
  244.             FPrintf(filhandle,"@ENDNODE\n\n");
  245.           }
  246.           /* MAKE ROOM IN THE ARRAY FOR EACH AREA */
  247.           sekarray[0]=sekarrayptr;
  248.           sekarray2[0]=sekarrayptr;
  249.           for(i=1;i<100;i++)
  250.           {
  251.             sekarray[i]=sekarray[i-1]+files[i-1];
  252.             sekarray2[i]=sekarray[i];
  253.           }
  254.           /* PUT ALL INTERESTING FILES IN THE ARRAY */
  255.           filptr=(struct maxfileentry *)&srcmem->the_rest;
  256.           for(i=0;i<srcmem->filetotal;i++)
  257.           {
  258.             if (!filptr->flags&~4)
  259.               if (!maxage || dato.ds_Days-filptr->dato<maxage)
  260.                 *(sekarray[filptr->area]++)=filptr;
  261.             filptr++;
  262.           }
  263.           /* SORT THE ARRAY BY FILENAMES */
  264.           for(i=0;i<100;i++)
  265.             if(files[i]>0)
  266.               qsort(sekarray2[i],files[i],sizeof(APTR),&comp);
  267.           /* INITIALIZE DATESTAMP */
  268.           datotid.dat_Stamp.ds_Minute=0;
  269.           datotid.dat_Stamp.ds_Tick=0;
  270.           datotid.dat_Format=FORMAT_DOS;
  271.           datotid.dat_Flags=0;
  272.           datotid.dat_StrDay=NULL;
  273.           datotid.dat_StrDate=tidstreng;
  274.           datotid.dat_StrTime=NULL;
  275.           /* INCLUDE INFOPAGE HERE IF WANTED */
  276.           if (info)
  277.           {
  278.             if(!simplelist)
  279.               FPrintf(filhandle,"\n@NODE \"infosektion\" \"%s\"\n",bbsname);
  280.             Flush(filhandle);
  281.             Write(filhandle,infmem,infsiz);
  282.             if(!simplelist)
  283.               FPrintf(filhandle,"\n@ENDNODE\n");
  284.           }
  285.           /* FORMAT AND PRINT ALL THE FILES */
  286.           for(i=0;i<100;i++)
  287.           {
  288.             totalareabytes=0;
  289.             if(inkluder[i] && files[i])
  290.             {
  291.               /* PRINT FILES IN ONE SECTION */
  292.               if(simplelist)
  293.                 FPrintf(filhandle,"\n---------------------------------------------------------------------------\n                        \"%s\""\
  294.                 "\n---------------------------------------------------------------------------\n\n",conmem+2496+i*62);
  295.               else
  296.                 FPrintf(filhandle,"\n@NODE \"Section%ld\" \"%s\"\n",(LONG)i,conmem+2496+i*62);
  297.               for(j=0;j<files[i];j++)
  298.               {
  299.                 datotid.dat_Stamp.ds_Days=(*(sekarray2[i]+j))->dato;
  300.                 DateToStr(&datotid);
  301.                 s=formatfile(*(sekarray2[i]+j),tidstreng,dato.ds_Days-datotid.dat_Stamp.ds_Days<30);
  302.                 FPuts(filhandle,s);
  303.                 totalareabytes+=(*(sekarray2[i]+j))->siz;
  304.               }
  305.               FPrintf(filhandle,"\nTotally %ld bytes in %ld files\n",totalareabytes,files[i]);
  306.               if(!simplelist) FPrintf(filhandle,"@ENDNODE\n");
  307.             }
  308.           }
  309.           /* ALL OVER.. FREE WHAT WAS USED */
  310.           FreeVec(sekarrayptr);
  311.         }
  312.         Close(filhandle);
  313.       FreeVec(conmem);
  314.       } else printf("Couldn't open output file. Now beam me up, Scotty.\n");
  315.     }
  316.   FreeVec(srcmem);
  317.   }
  318.   if(info)
  319.     FreeVec(infmem);
  320.   return(0);
  321. }
  322.